using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MatrixFramework.Shared.Contracts.Governance
{
    /// <summary>
    /// 服务治理相关合约
    /// 可被所有服务重用的治理功能
    /// </summary>

    // 服务注册与发现
    public interface IServiceRegistryAppService
    {
        Task<ServiceRegistrationDto> RegisterServiceAsync(RegisterServiceInput input);
        Task<bool> UnregisterServiceAsync(string serviceId);
        Task<List<ServiceInstanceDto>> GetServiceInstancesAsync(string serviceName);
        Task<ServiceInstanceDto> GetHealthyInstanceAsync(string serviceName);
    }

    // 限流控制
    public interface IRateLimitingAppService
    {
        Task<RateLimitResult> CheckRateLimitAsync(RateLimitRequest request);
        Task UpdateRateLimitConfigAsync(UpdateRateLimitConfigInput input);
        Task<RateLimitConfigDto> GetRateLimitConfigAsync(string clientId);
    }

    // 熔断器
    public interface ICircuitBreakerAppService
    {
        Task<CircuitBreakerStatusDto> GetCircuitBreakerStatusAsync(string serviceName);
        Task<bool> IsCircuitOpenAsync(string serviceName);
        Task ResetCircuitBreakerAsync(string serviceName);
        Task UpdateCircuitBreakerConfigAsync(UpdateCircuitBreakerConfigInput input);
    }

    // DTO定义
    public class ServiceRegistrationDto
    {
        public string ServiceId { get; set; } = string.Empty;
        public string ServiceName { get; set; } = string.Empty;
        public string Version { get; set; } = string.Empty;
        public List<string> Tags { get; set; } = new();
        public DateTime RegistrationTime { get; set; }
        public DateTime LastHeartbeat { get; set; }
    }

    public class ServiceInstanceDto
    {
        public string InstanceId { get; set; } = string.Empty;
        public string ServiceName { get; set; } = string.Empty;
        public string Host { get; set; } = string.Empty;
        public int Port { get; set; }
        public string Protocol { get; set; } = "http";
        public Dictionary<string, string> Metadata { get; set; } = new();
        public bool IsHealthy { get; set; }
        public DateTime LastCheck { get; set; }
    }

    public class RegisterServiceInput
    {
        public string ServiceName { get; set; } = string.Empty;
        public string Version { get; set; } = "1.0.0";
        public string Host { get; set; } = string.Empty;
        public int Port { get; set; }
        public string Protocol { get; set; } = "http";
        public List<string> Tags { get; set; } = new();
        public Dictionary<string, string> Metadata { get; set; } = new();
        public HealthCheckConfig HealthCheck { get; set; } = new();
    }

    public class HealthCheckConfig
    {
        public string Path { get; set; } = "/health";
        public int IntervalSeconds { get; set; } = 30;
        public int TimeoutSeconds { get; set; } = 5;
        public string Method { get; set; } = "GET";
    }

    public class RateLimitRequest
    {
        public string ClientId { get; set; } = string.Empty;
        public string Resource { get; set; } = string.Empty;
        public int RequestCount { get; set; } = 1;
        public Dictionary<string, string> Context { get; set; } = new();
    }

    public class RateLimitResult
    {
        public bool IsAllowed { get; set; }
        public int RemainingRequests { get; set; }
        public long ResetTime { get; set; }
        public string? Reason { get; set; }
    }

    public class RateLimitConfigDto
    {
        public string ClientId { get; set; } = string.Empty;
        public int RequestsPerSecond { get; set; }
        public int BurstCapacity { get; set; }
        public Dictionary<string, int> ResourceLimits { get; set; } = new();
        public DateTime UpdatedAt { get; set; }
    }

    public class UpdateRateLimitConfigInput
    {
        public string ClientId { get; set; } = string.Empty;
        public int RequestsPerSecond { get; set; }
        public int BurstCapacity { get; set; }
        public Dictionary<string, int> ResourceLimits { get; set; } = new();
    }

    public class CircuitBreakerStatusDto
    {
        public string ServiceName { get; set; } = string.Empty;
        public CircuitBreakerState State { get; set; }
        public DateTime LastStateChange { get; set; }
        public int FailureCount { get; set; }
        public int SuccessCount { get; set; }
        public DateTime LastFailureTime { get; set; }
    }

    public enum CircuitBreakerState
    {
        Closed,
        Open,
        HalfOpen
    }

    public class UpdateCircuitBreakerConfigInput
    {
        public string ServiceName { get; set; } = string.Empty;
        public int FailureThreshold { get; set; } = 5;
        public TimeSpan RecoveryTimeout { get; set; } = TimeSpan.FromMinutes(1);
        public int SuccessThreshold { get; set; } = 3;
        public TimeSpan MonitoringPeriod { get; set; } = TimeSpan.FromMinutes(5);
    }
}